#!/usr/bin/env bash
start_time=$(date +%s)
# Takes around 2:20 hours to run (1:30 experiments + 0:50 supplementary) 
# Options:
# 1. Run all the classification and evaluation for annotated set (Default) --> flag_test=false
# 2. Run all the classification and evaluation for annotated set and test set (90+ GB and 2-3 days of computation) --> flag_test=true
flag_test=false  # Set to "flag_test=true" if you want to download and compute tracking and classification for all TV.

# Download and prepare data folder
# Takes around 4 minutes
# This contains:
# Download the embeddings corresponding to the individuals' models
# Download precomputed detections and face features embeddedings
# Download ground truth data for evaluation
echo "Downloading data..."
if "$flag_test"; then
    # Download annotated and test data and run classification over it. Note that this will take 2-3 days and 90+ GB.
    # We are currently uploading the file.
    wget --no-check-certificate www.satoh-lab.nii.ac.jp/member/agirbau/telestats/files/data_all.tar.gz
    tar -xf data_all.tar.gz data
    rm /code/data_all.tar.gz
else
    # Download annotated data and run classification over it (Default). We provide pre-computed results for test data. 
    wget --no-check-certificate www.satoh-lab.nii.ac.jp/member/agirbau/telestats/files/data.tar.gz
    tar -xf data.tar.gz data
    rm /code/data.tar.gz
fi
ls -lh
echo "...Done!"

# Channel list
# news7-lv (NHK), hodost-lv (HODO Station), CNNW (CNN), FOXNEWSW (FOX), MSNBCW (MSNBC)
channel_list=("CNNW" "FOXNEWSW" "MSNBCW" "news7-lv" "hodost-lv")  
detector_list=("dfsd" "mtcnn" "yolo")
feats_list=("resnetv1")  # resnetv1 (Inception-resnet as backbone)
# knn_3 (KNN), fcg_average_centroid (centroid), fcg_average_vote (vote), fcgNT_average_vote (for "No Tracking" vote experiment in Table 6)
classifier_list=("knn_3" "fcg_average_centroid" "fcg_average_vote" "fcgNT_average_vote")  

# Quick test
#channel_list=("CNNW")  
#detector_list=("yolo")
#feats_list=("resnetv1")  # resnetv1 (Inception-resnet as backbone)
#classifier_list=("fcg_average_vote")  

# Run classification for all the different options
echo "Running tracking and classification for all channels..."
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for detector in "${detector_list[@]}"; do
        for feats in "${feats_list[@]}"; do
            for classifier in "${classifier_list[@]}"; do
                python src/face_classifier.py train "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier"
            done
        done
    done
done
echo "...Done!"


# Table 3
# Amount of missed detections for the specified detector
# Takes around 3-4 minutes to execute all combinations
echo "Computing amount of missed detections for each channel-detector pair..."
echo "Metrics for channel-detector:" >> /results/output
echo "Table 3:" >> /results/output
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for detector in "${detector_list[@]}"; do
        python src/metrics.py train "$channel" --models_path "data/$models_path" --detector "$detector" --modifier sf --use_dets | tee -a /results/output
    done
done
echo "...Done!"
echo $'\n' >> /results/output

# Tables 4, 5, 6
# Run evaluation for the specified options (detector + classifier)
# Takes around 15 minutes to execute all combinations
echo "Computing metrics for channel-detector-classifier triplet..."
echo "Metrics for channel-detector-classifier:" >> /results/output
echo "Tables 4, 5, 6:" >> /results/output
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for classifier in "${classifier_list[@]}"; do
        for detector in "${detector_list[@]}"; do
            for feats in "${feats_list[@]}"; do
                # Extract data for further analysis
                python src/metrics.py train "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier"
                # Compute metrics for results
                python src/metrics.py train "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier" --modifier sf | tee -a /results/output
            done
        done
    done
done
echo "...Done!"
echo $'\n' >> /results/output


# Figures 5-6
# Generate dataset with fiftyone
# Takes around 5 minutes
echo "Converting data to fiftyone-like dataset..."
python src/convert_dataset_to_fiftyone.py
echo "...Done!"

# Populate the dataset with the detections/classification of the key individuals
# Takes around 13 minutes
echo "Populating the dataset with results..."
python src/convert_results_to_fiftyone.py
echo "...Done!"

# Generate F1 and mAP plots for all channels with respect to face size
# Results are saved to /results
echo "Computing F1 and mAP plots with respect to face size..."
python src/run_fiftyone_f1_map.py
echo "...Done!"

# Table 7 and Figure 7
# The following code reproduces table 7 and figure 7, which are computed over all *daily* videos from the past 10-20 years. 
# As it is both heavy (90+ GB) and computationally intensive (2-3 days to compute for all the data), we provide our precomputed results for tracking + classification. If interested on generating and classifying all the data, please change the initial flag in "Options" to flag_test=true.

if "$flag_test"; then
# Run classification for test over yolo-vote configuration
detector_list=("yolo")
classifier_list=("fcg_average_vote") 

echo "Running tracking and classification for all channels..."
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for detector in "${detector_list[@]}"; do
        for feats in "${feats_list[@]}"; do
            for classifier in "${classifier_list[@]}"; do
                python src/face_classifier.py demo "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier"
            done
        done
    done
done
echo "...Done!"

echo "Extracting test data for channel-detector-classifier triplet..."
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for classifier in "${classifier_list[@]}"; do
        for detector in "${detector_list[@]}"; do
            for feats in "${feats_list[@]}"; do
                # Extract data for further analysis
                python src/metrics.py demo "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier"
            done
        done
    done
done
echo "...Done!"
fi

# Table 7
python src/analysis.py tab7 | tee -a /results/output

# Figures 7a 7b
python src/analysis.py fig7


#### Supplementary material experiments ###
# Takes 50 minutes
# Experiment 1
# Threshold sweep in voting for FCG classification 
detector_list=("yolo")
 
perc_votes=("0.1" "0.15" "0.2" "0.25" "0.3" "0.35" "0.4" "0.45" "0.5" "0.55" "0.6" "0.65" "0.7" "0.75" "0.8" "0.85" "0.9" "0.95" "0.99")
mod_feat=("fcg_average_vote_01" "fcg_average_vote_015" "fcg_average_vote_02" "fcg_average_vote_025" "fcg_average_vote_03" "fcg_average_vote_035" "fcg_average_vote_04" "fcg_average_vote_045" "fcg_average_vote_05" "fcg_average_vote_055" "fcg_average_vote_06" "fcg_average_vote_065" "fcg_average_vote_07" "fcg_average_vote_075" "fcg_average_vote_08" "fcg_average_vote_085" "fcg_average_vote_09" "fcg_average_vote_095" "fcg_average_vote_099")

# Run classification for all the different options
echo "Supplementary Material 1: Running tracking and classification with a sweeping threshold for all channels..."
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    results_path=data/results/"$channel"/train/results
    mkdir "$results_path"

    for detector in "${detector_list[@]}"; do
        for i in "${!mod_feat[@]}"; do
            mod=${mod_feat[i]}
            perc_vote=${perc_votes[i]}

            # Run classification for specific threshold
            python src/face_classifier.py train "$channel" --models_path "data/$models_path" --detector "$detector" --mod_feat "$mod" --perc_votes "$perc_vote"

            # Run evaluation
            res_file="$results_path"/"$detector"-"resnetv1"-"$mod"-sf.txt
            python src/metrics.py train "$channel" --models_path "data/$models_path" --detector "$detector" --mod_feat "$mod" --modifier sf  > "$res_file"

        echo "...done!"
        done
    done
done
echo "...Done!"

# Figures SM 1-3, Table 1-2
python src/supplementary_experiments_1.py

# Experiment 2
# Use facenet features to compare with Hong et al. paper
#channel_list=("CNNW")  
#detector_list=("mtcnn")
#feats_list=("facenet")  
#classifier_list=("fcg_average_vote") 

channel_list=("CNNW" "FOXNEWSW" "MSNBCW")  
detector_list=("mtcnn")
feats_list=("facenet" "resnetv1")  
classifier_list=("fcg_average_vote" "fcgNT_average_vote")  

# Run classification for all the different options
echo "Supplementary Material 2: Running tracking and classification for MTCNN-facenet..."
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for detector in "${detector_list[@]}"; do
        for feats in "${feats_list[@]}"; do
            for classifier in "${classifier_list[@]}"; do
                python src/face_classifier.py train "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier"
            done
        done
    done
done
echo "...Done!"

# SM Table 3
# Run evaluation for the specified options (detector + classifier)
echo "Computing metrics for channel-detector-classifier triplet..."
echo "Metrics for SM channel-detector-classifier:" >> /results/output
echo "SM Table 3:" >> /results/output
for channel in "${channel_list[@]}"; do
    models_path="faces_politicians"
    if [[ "$channel" != "news7-lv" && "$channel" != "hodost-lv" ]]; then
        models_path="faces_us_individuals"
    fi

    for classifier in "${classifier_list[@]}"; do
        for detector in "${detector_list[@]}"; do
            for feats in "${feats_list[@]}"; do
                # Provide feats header
                echo "$feats" | tee -a /results/output
                # Compute metrics for results
                python src/metrics.py train "$channel" --models_path "data/$models_path" --detector "$detector" --feats "$feats" --mod_feat "$classifier" --modifier sf | tee -a /results/output
            done
        done
    done
done
echo "...Done!"
echo $'\n' >> /results/output


# Beautify tables for all experiments
python src/parse_results_to_tables.py


end_time=$(date +%s)
elapsed_time=$((end_time - start_time))
echo "Elapsed: $elapsed_time seconds"